# # from django.core.serializers import serialize
# # 导入 api_view 来处理请求判断
# from urllib import request
#
# from rest_framework import status
# from rest_framework.decorators import api_view, action
#
# from rest_framework.response import Response
#
# from user.models import User
# from user.serailizers import UserSerializer, AddressSerializer, AddressModelSerializer
#
# # Create your views here.
# """
# api_view：1.限定请求方式为GET，如果请求方式不正确，会返回405错误（请求方式不正确）
#               drf 支持的请求方式有：GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS等
#                   GET: 获取数据
#                   POST: 新增数据,一般返回201状态码（创建成功）
#                   PUT: 修改数据(全改)
#                   PATCH: 修改数据（部分该）
#                   OPTIONS:预检请求，多用于复杂度 ajax 请求
#                   HEAD: 获取响应头
#           2.将Django中的 request 对象自动更改为 drf 中的 request
#               在drf中，request对象接收页面传递的参数，使用request.query_params
#               表单参数，json格式的参数, 文件对象使用 request.data 来接收
#
#               其他用法参考django中的 request
#           3.drf中的request 包含了一些特殊的数据，可以更加方便高效管理接口
# """
# # # 使用  FBV（Function-Based Views，基于函数的视图） 模式来处理请求
# # @api_view(['GET'])
# # def user_list(request):
# #     # print("查询参数:", request.query_params)
# #     # print("表单/JSON参数", request.data)
# #     # print("文件对象", request.data)
# #
# #     queryset = User.objects.all()
# #     # 创建一个序列化对象, 如果序列化数据是一queryset对象，需要设置many=True
# #     # 如果序列化数据是一个对象，不需要设置many=True
# #     serializer = UserSerializer(instance=queryset, many=True, context={'request': request})
# #
# #     # 返回数据 - 修改这里，使用serializer.data获取序列化后的数据
# #     return Response(data=serializer.data)
# #
# #
# # @api_view(['GET'])
# # def user_detail(request, pk):
# #     try:
# #         user = User.objects.get(pk=pk)
# #         # 定义一个序列化器
# #         serializer = UserSerializer(instance=user)
# #         return Response(data=serializer.data, status=200)
# #
# #     except:
# #         return Response(status=404, data={"message": "未找到数据"})
# #
# #
# # # 1.增加用户
# # @api_view(['POST'])
# # def user_add(request):
# #     # 1.接收传入的数据
# #     # 创建序列化器对象，接收
# #     serializer = UserSerializer(data=request.data)
# #     # 2.校验数据(必须)
# #     if serializer.is_valid():
# #         # 校验成功说明传入的数据符合要求
# #         queryset = User.objects.filter(username=request.data.get("username"))
# #         # 判断用户名是否被注册
# #         if queryset:
# #             return Response(status=400, data={"message": "用户名已存在"})
# #
# #         # 将数据保存到数据库中
# #         # 3.插入数据（需要在序列化器中提供create（）方法来完成）
# #         serializer.save()
# #         return Response(status=201, data=serializer.data)
# #
# #     # 如果校验失败，返回错误信息
# #     return Response(serializer.errors, status=400)
# #
# #
# # # 2.修改用户
# # @api_view(['PUT'])
# # def user_modify(request, pk):
# #     # 根据主键查询对应的模型
# #     try:
# #         user = User.objects.get(pk=pk)
# #
# #     except:
# #         return Response(status=404, data={"message": "未找到数据"})
# #
# #     # 创建一个序列化器对象，接收页面数据
# #     serializer = UserSerializer(instance=user, data=request.data)
# #     # 校验数据、如果校验失败，会返回400状态码
# #     serializer.is_valid(raise_exception=True)
# #     # 如果校验成功，修改数据
# #     serializer.save()
# #     return Response(data=serializer.data, status=200)
# #
# #
# # # 3.删除用户
# # @api_view(['DELETE'])
# # def user_delete(request, pk):
# #     # 真删除，如果软删除修改状态就行
# #     User.objects.filter(pk=pk).delete()
# #     # 删除成功返回204状态码
# #     return Response(status=204)
# #
# #
# # # 4.查询用户
# # @api_view(['GET'])
# # def user_query(request, pk):
# #     try:
# #         # 获取查询的用户
# #         user = User.objects.get(pk=pk)
# #         serialize = UserSerializer(instance=user)
# #         # 校验数据（处理GET请求时候不需要添加）
# #         # serializer.is_valid(raise_exception=True)
# #         return Response(data=serialize.data, status=200)
# #
# #     except:
# #         return Response(status=404, data={"message": "未找到数据"})
# #
# #
# # # 5.查询所有用户
# # @api_view(['GET'])
# # def user_queryall(request):
# #     try:
# #         # 查询所有用户信息
# #         users = User.objects.all()
# #         # 创建序列化对象，接收数据
# #         serializer = UserSerializer(instance=users, many=True)
# #         # 校验数据（处理GET请求时候不需要添加）
# #         # serializer.is_valid(raise_exception=True)
# #         return Response(data=serializer.data, status=200)
# #
# #     except:
# #         return Response(status=404, data={"message": "未找到数据"})
# #
# #
# # @api_view(['POST'])
# # def address_add(request):
# #     # 1.创建序列化器对象，接收页面数据
# #     serializer = AddressSerializer(data=request.data)
# #     # 2.进行数据校验
# #     if serializer.is_valid():
# #         # 3.校验成功，保存数据
# #         serializer.save()
# #         return Response(data=serializer.data, status=201)
# #
# #
# # @api_view(['PUT'])
# # def address_modify(request, pk):
# #     # 根据主键查询对应的收货地址
# #     try:
# #         address = Address.objects.get(pk=pk)
# #
# #     except:
# #         return Response(status=404, data={"message": "收货地址不存在"})
# #
# #     # 创建一个序列化对象
# #     serializer = AddressModelSerializer(instance=address, data=request.data)
# #     serializer.is_valid(raise_exception=True)
# #     serializer.save()
# #     # 返回数据
# #     return Response(data=serializer.data, status=200)
# #
# #
# # @api_view(['GET'])
# # def address_list(request):
# #     # 查询所有的收货地址
# #     addresses = Address.objects.all()
# #     # 创建序列化器对象
# #     # 方式4. 使用HyperlinkedRelatedField，将user 变成一个超链接，指向user的详情页面
# #     # context = {'request': request} 会返回绝对路径
# #     # context = {'request': request} 会返回相对路径 ，去掉http://...
# #     serializer = AddressSerializer(instance=addresses, many=True, context={'request': request},
# #                                    # 设置 fields 来指定返回的字段，只返回id，user，province，city
# #                                    fields=['id', 'user', 'province', 'city']
# #                                    )
# #     # 返回数据
# #     return Response(data=serializer.data, status=200)
# #
# #
# # @api_view(['DELETE'])
# # def address_delete(request, pk):
# #     # 真删除，如果软删除修改状态就行
# #     Address.objects.get(pk=pk).delete()
# #     # 删除成功返回204状态码
# #     return Response(status=204)
#
# from rest_framework.views import APIView
# from rest_framework.generics import GenericAPIView
#
# from rest_framework.viewsets import GenericViewSet
#
# """
# GenericAPIView:
#
#     queryset:用来设置查询集
#
#     serializer_class:用来设置序列化器
#
#     get_queryset():用来获取查询集
#
#     get_serializer():用来获取序列化器
#
#     get_object():用来获取单个对象(根据pk主键查询单个对象),如果参数不叫pk 可以通过 lookup_field来设置
#
#     paginate_queryset():获取分页后的查询集
#
#     get_paginated_response():获取分页后的响应
#
#     get_serializer_context():用来获取序列化器的上下文
#     get_serializer_class():用来获取序列化器的类
#
# GenericViewSet:
#     继承GenericAPIView,提供了增删改查的方法
#     继承ViewSetMixin,
#     ViewSetMixin 解决了 CBV 类中 必须提供 和请求方式相同的方法名 ，可以让类中的方法名任意
#     但是在定义路由的时候，必须指定 请求方式 和 方法名的映射关系
#
#
#
#
#
# """
#
# # # 1.第一版本：使用 CBV（Class-Based Views，基于类的视图） 来处理请求判断
# # class UserView(GenericAPIView):
# #     queryset = User.objects.all()
# #     serializer_class = UserSerializer
# #
# #     def get(self, request, *args, **kwargs):
# #         if "pk" in kwargs:
# #             instance = self.get_object()
# #             serializer = self.get_serializer(instance=instance)
# #
# #             return Response(data=serializer.data)
# #
# #         # 如果不包含pk，则直接查找用户
# #         serializer = self.get_serializer(instance=self.get_queryset(), many=True)
# #         return Response(data=serializer.data)
# #
# #     def post(self, request, *args, **kwargs):
# #         # 接收参数获取序列化对象
# #         serializer = self.get_serializer(data=request.data)
# #         # 校验
# #         serializer.is_valid(raise_exception=True)
# #         # 保存数据
# #         serializer.save()
# #         return Response(data=serializer.data, status=status.HTTP_201_CREATED)
# #
# #     def put(self, request, *args, **kwargs):
# #         instance = self.get_object()
# #
# #         # 获取
# #         serializer = self.get_serializer(instance, data=request.data)
# #         # 校验
# #         serializer.is_valid(raise_exception=True)
# #         # 保存
# #         serializer.save()
# #         return Response(data=serializer.data, status=status.HTTP_200_OK)
# #
# #     def delete(self, request, *args, **kwargs):
# #         self.get_object().delete()
# #         return Response(status=status.HTTP_204_NO_CONTENT)
# #
# #
# # class AddressView(GenericAPIView):
# #     queryset = Address.objects.all()
# #     serializer_class = AddressSerializer
# #
# #     def get(self, request, *args, **kwargs):
# #         if "pk" in kwargs:
# #             instance = self.get_object()
# #             serializer = self.get_serializer(instance=instance)
# #
# #             return Response(data=serializer.data)
# #
# #         # 如果不包含pk，则直接查找用户
# #         serializer = self.get_serializer(instance=self.get_queryset(), many=True)
# #         return Response(data=serializer.data)
# #
# #     def post(self, request, *args, **kwargs):
# #         # 接收参数获取序列化对象
# #         serializer = self.get_serializer(data=request.data)
# #         # 校验
# #         serializer.is_valid(raise_exception=True)
# #         # 保存数据
# #         serializer.save()
# #         return Response(data=serializer.data, status=status.HTTP_201_CREATED)
# #
# #     def put(self, request, *args, **kwargs):
# #         instance = self.get_object()
# #
# #         # 获取
# #         serializer = self.get_serializer(instance, data=request.data)
# #         # 校验
# #         serializer.is_valid(raise_exception=True)
# #         # 保存
# #         serializer.save()
# #         return Response(data=serializer.data, status=status.HTTP_200_OK)
# #
# #     def delete(self, request, *args, **kwargs):
# #         self.get_object().delete()
# #         return Response(status=status.HTTP_204_NO_CONTENT)
#
#
# # # 2.第二版本：使用 CBV（Class-Based Views，基于类的视图） 来处理请求判断
# # from rest_framework.mixins import ListModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, \
# #     CreateModelMixin
# #
# #
# # class UserView(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, CreateModelMixin, GenericAPIView):
# #     queryset = User.objects.all()
# #     serializer_class = UserSerializer
# #
# #     def get(self, request, *args, **kwargs):
# #         if "pk" in kwargs:
# #             return self.retrieve(request, *args, **kwargs)
# #
# #         return self.list(request, *args, **kwargs)
# #
# #     def post(self, request, *args, **kwargs):
# #         return self.create(request, *args, **kwargs)
# #
# #     def put(self, request, *args, **kwargs):
# #         return self.update(request, *args, **kwargs)
# #
# #     def delete(self, request, *args, **kwargs):
# #         return self.destroy(request, *args, **kwargs)
# #
# #
# # class AddressView(ListModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, CreateModelMixin, GenericAPIView):
# #     queryset = Address.objects.all()
# #     serializer_class = AddressSerializer
# #
# #     def get(self, request, *args, **kwargs):
# #         if "pk" in kwargs:
# #             return self.retrieve(request, *args, **kwargs)
# #
# #         return self.list(request, *args, **kwargs)
# #
# #     def post(self, request, *args, **kwargs):
# #         return self.create(request, *args, **kwargs)
# #
# #     def put(self, request, *args, **kwargs):
# #         return self.update(request, *args, **kwargs)
# #
# #     def delete(self, request, *args, **kwargs):
# #         return self.destroy(request, *args, **kwargs)
#
#
# # 3.第三版本：使用 CBV（Class-Based Views，基于类的视图） 来处理请求判断
# from rest_framework.viewsets import ModelViewSet
# from rest_framework.decorators import action
# from rest_framework.pagination import PageNumberPagination
# from rest_framework.permissions import AllowAny, IsAuthenticated
#
#
# """
# GenericViewSet:
#     继承GenericAPIView,提供了增删改查的方法
#     继承ViewSetMixin,
#     ViewSetMixin 解决了 CBV 类中 必须提供 和请求方式相同的方法名 ，可以让类中的方法名任意
#     但是在定义路由的时候，必须指定 请求方式 和 方法名的映射关系
#
# ReadOnlyModelViewSet:
#     内置了查询方法，默认继承了ListModelMixin, RetrieveModelMixin, GenericViewSet
#
# ModelViewSet:
#     内置了增删改查方法，默认继承了ListModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, CreateModelMixin,
#      GenericViewSet
# """
#
#
# # class UserView(ModelViewSet):
# #     queryset = User.objects.all()
# #     serializer_class = UserSerializer
# #
# #     # 设置使用哪一种方式进行分页
# #     pagination_class = PageNumberPagination
# #     # 页面传入 rows 用来进行分页、如果不匹配，需要传入 page_size
# #     PageNumberPagination.page_size_query_param = "rows"
# #     # 修改默认的 page 为 page
# #     PageNumberPagination.page_query_param = "page"
# #
# #     # 重写 list 方法，进行分页处理
# #     def list(self, request, *args, **kwargs):
# #         queryset = self.get_queryset()
# #         # 对查询集进行分页（核心）
# #         page = self.paginate_queryset(queryset)
# #         # 对配置内容进行序列化
# #         serializer = self.get_serializer(page, many=True)
# #         # 将当前页码 对应的数据 传给 get_paginated_response（核心）
# #         return self.get_paginated_response(serializer.data)
# #
# #
# # class AddressView(ModelViewSet):
# #     queryset = Address.objects.all()
# #     serializer_class = AddressSerializer
# #
# #     # 局部配置登录
# #     permission_classes = [AllowAny]
# #
# #     # 根据用户id查询地址
# #     # detail 如果设置成 True，则代表 会根据当前模型的 ID 来查询数据， 在url_path 指定的路由前面会自动添加一个pk路径参数
# #     # detail 如果设置成 True，url_path 设置的路由 为4级路由，3级路由 是 动态参数路由，要求传入一个pk
# #     @action(methods=['GET'], detail=False, url_path="find/(?P<user_id>\d+)", url_name="find-by-uid",
# #             # 设置权限，只有登录用户才能访问
# #             # permission_classes=[IsAuthenticated]
# #             )
# #     def query_list_by_userid(self, request, user_id):
# #         """
# #         根据用户id查询地址
# #         :param request:
# #         :param user_id:
# #         :return:
# #         """
# #         queryset = self.get_queryset().filter(user_id=user_id)
# #         serializer = self.get_serializer(queryset, many=True)
# #         return Response(data=serializer.data, status=status.HTTP_200_OK)
from django.core import serializers
from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

from djangoProject12.serializers import DynamicFieldsModelSerializer
from user.models import User, Role, Clazz
from user.serailizers import UserFormSerializer, RoleSerializer, ClazzSerializer, UsersSerializer


class UserViewSet(viewsets.GenericViewSet):
    queryset = User.objects.filter(is_delete=False)
    serializer_class = UserFormSerializer
    pagination_class = PageNumberPagination
    PageNumberPagination.page_size_query_param = "rows"

    def create(self, request, *args, **kwargs):
        # 接收页面传入的数据
        serializer = self.get_serializer(data=request.data)

        # 校验
        serializer.is_valid(raise_exception=True)
        # 保存
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        page = self.paginate_queryset(queryset)
        # 对page对象进行序列化操作
        serializer = UsersSerializer(page, many=True, exclude=['password'])
        # 返回分页结果
        return self.get_paginated_response(serializer.data)

    @action(methods=['GET'], detail=False, url_path="find-role-clazz-list", url_name="role-class-list")
    def find_role_and_class_list(self, request, *args, **kwargs):
        # 查询所有角色信息
        roles_queryset = Role.objects.filter(is_delete=False, state=True)
        # 查询所有班级信息
        class_queryset = Clazz.objects.filter(is_delete=False, state=True)

        role_serializer = RoleSerializer(roles_queryset, many=True, fields=["id", "name"])

        class_serializer = ClazzSerializer(class_queryset, many=True)

        data = {
            "roleList": role_serializer.data,
            "clazzList": class_serializer.data
        }

        return Response(data, status=status.HTTP_200_OK)


# 首先自定义一个分页类
class CustomPageNumberPagination(PageNumberPagination):
    page_size_query_param = "rows"
    page_query_param = "page"

